import { noop } from './utils/noop';
import { onview } from './utils/on-view';
import { thrower } from './utils/thrower';
import { loadImage } from './utils/load-image';

/**
 * 用例:
 * `<img src="blank.gif" data-src="my_image.png" width="600" height="400" class="lazy-image">`
 * 
 * 说明:
 * 初始时，须要懒加载的图片区不在视口之内，因此无需图像占位
 * @param selector 须加载的图像目标的类名，默认: .lazy-image
 * @param attribute 存储图片真实路径的属性名，必须是 .lazy-image 元素的属性，须HTML5数据属性规范，默认: data-src
 * @param loading 图片加载过程中的 loading ，必须是一个有效的 css 类名，默认: .lazy-loading
 * @param throttle touchmove scroll 事件节流时间，阻止频繁执行，默认: 150ms 
 * @param onerror 某个图片加载失败时的处理函数，传出了懒加载对象，onerror(elem) 
 * @param imgUseBackgroundImage 若懒加载对象是一个img对象，是否将加载成功的图像设置为其背景图片，默认: true
 **/
export function lazyLoadImage(opts) {
    // 命名空间，有助于控制台快速区分错误发生地点
    const namespace = '[lazyLoadImage Exception]';

    if ('object' !== typeof opts) { 
        return thrower(namespace, 'Invalid Options, It has to be an object.');
    }

    const { DEFAULT } = lazyLoadImage;
    const selector = 'string' === typeof opts.selector
        ? opts.selector
        : DEFAULT.selector;
    const attribute = 'string' === typeof opts.attribute
        ? opts.attribute
        : DEFAULT.attribute;
    const loading = 'string' === typeof opts.loading
        ? opts.loading
        : DEFAULT.loading;
    const throttle = 'number' === typeof opts.throttle && !isNaN(opts.throttle)
        ? opts.throttle
        : DEFAULT.throttle;
    const onerror = 'function' === typeof opts.onerror
        ? opts.onerror
        : DEFAULT.onerror;
    const imgUseBackgroundImage = Boolean(opts.imgUseBackgroundImage) || DEFAULT.imgUseBackgroundImage;

    // 程序变量
    const target = document.querySelectorAll(selector);
    const queues = [...target];

    // 定时器处理函数
    function timeoutHandler() {

        queues.forEach(function (elem, index) {
            if (onview(elem)) {
                const src = elem.getAttribute(attribute);

                // 读取图片
                loadImage(src, function (flag) {
                    if (flag) {

                        // 当图片加载成功
                        if (elem.tagName !== "IMG" || imgUseBackgroundImage) {
                            elem.style.backgroundImage = "url('" + src + "')";
                        } else {
                            elem.src = src;
                        }

                        // 从懒加载队列里踢出当前懒加载对象
                        queues.splice(index, 1);
                        elem.removeAttribute(attribute);
                    } else {
                        onerror(elem);
                    }
                });
            }
        });
    }

    // scroll touchmove 事件监听器，使用定时器做节流处理
    function listener() {

        // 图片全部加载完成之后，解除事件监听
        if (queues.length === 0) {
            window.removeEventListener('scroll', listener);
            window.removeEventListener('touchmove', listener);
            return;
        }

        // 清除定时器
        if (listener.timer) {
            listener.timer = null;
            clearTimeout(listener.timer);
        }
        

        // 定时器句柄 
        listener.timer = setTimeout(timeoutHandler, throttle);
    };

    listener(); // 加载首屏
    window.addEventListener('scroll', listener);
    window.addEventListener('touchmove', listener);
}

// 默认的配置项
lazyLoadImage.DEFAULT = {
    selector: '.lazy-image',
    attribute: 'data-src',
    loading: '.lazy-loading',
    throttle: 150,
    onerror: noop,
    imgUseBackgroundImage: true
}